package com.jfinal.weixin.mvc.jfinal;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.kit.SignatureCheckKit;
import lombok.extern.slf4j.Slf4j;

/**
 * Msg 拦截器
 * 2：响应开发者中心服务器配置 URL 与 Token 请求
 * 3：签名检测
 * 注意： MsgController 的继承类如果覆盖了 index 方法，则需要对该 index 方法声明该拦截器
 * 因为子类覆盖父类方法会使父类方法配置的拦截器失效，从而失去本拦截器的功能
 */
@Slf4j
public class WeChatInterceptor implements Interceptor {

    @Override
    public void intercept(Invocation ai) {
        Controller controller = ai.getController();
        if (controller instanceof BasicWeChatMessageController == false)
            throw new RuntimeException("Controller could extends: BasicWeChatMessageController");
        try {
            /**
             * TODO 增加验证微信消息来源IP地址
             */

            // 如果是服务器配置请求，则配置服务器并返回
            if (isConfigServerRequest(controller)) {
                configServer(controller);
                return;
            }
            // 接收消息签名检测
            if (checkSignature(controller)) {
                ai.invoke();
            } else {
                controller.renderText("check signature failure.");
            }
        } catch (Exception e) {
            log.error("request illegal！" + e.getMessage());
            e.printStackTrace();
            return;
        }
    }

    /**
     * 是否为开发者中心保存服务器配置的请求
     */
    private Boolean isConfigServerRequest(Controller controller) {
        return StrKit.notBlank(controller.getPara("echostr"));
    }

    /**
     * 接收消息签名检测
     *
     * @param controller
     * @return
     */
    private Boolean checkSignature(Controller controller) {
        String signature = controller.getPara("signature");
        String timestamp = controller.getPara("timestamp");
        String nonce = controller.getPara("nonce");
        if (StrKit.isBlank(signature) || StrKit.isBlank(timestamp) || StrKit.isBlank(nonce)) {
            controller.renderText("check signature failure");
            return false;
        }

        /**
         * TODO 思考如何动态取得当前帐号的Token信息
         */
//        WeixinConfig wxConfig = WeixinConfigHandler.controller.getPara());

        if (SignatureCheckKit.ice.checkSignature("token", signature, timestamp, nonce)) {
            return true;
        } else {
            log.error("check signature failure: " +
                    " signature = " + controller.getPara("signature") +
                    " timestamp = " + controller.getPara("timestamp") +
                    " nonce = " + controller.getPara("nonce"));

            return false;
        }
    }

    /**
     * 配置开发者中心微信服务器所需的 url 与 token
     *
     * @return true 为config server 请求，false 正式消息交互请求
     */
    public void configServer(Controller c) {
        // 通过 echostr 判断请求是否为配置微信服务器回调所需的 url 与 token
        String echostr = c.getPara("echostr");
        String signature = c.getPara("signature");
        String timestamp = c.getPara("timestamp");
        String nonce = c.getPara("nonce");

        /**
         * TODO 思考如何动态取得当前帐号的Token信息
         */
        boolean isOk = SignatureCheckKit.ice.checkSignature("token", signature, timestamp, nonce);
        if (isOk) {
            log.debug("check config signature successful.");
            c.renderText(echostr);
        } else {
            c.renderText("check config signature failure.");
            log.error("消息来源签名验证失败");
        }
    }
}
